/////////////////////////////////////////////////////////////////////////////
// This file is part of the "Java-DAP" project, a Java implementation
// of the OPeNDAP Data Access Protocol.
//
// Copyright (c) 2007 OPeNDAP, Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
/////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections;
using System.IO;
using System.Text;
using NDODS.DAP;
using NDODS.DAP.BaseTypes;

namespace NDODS.DAP.Server
{
    /// <summary> ServerDDS is a specialization of DDS for the server-side of OPeNDAP. This
    /// class includes methods used to distinguish synthesized variables
    /// (variables added to the DDS by a constraint expression function), methods
    /// for CE function management and methods used to return a `constrained DDS'
    /// as part of a OPeNDAP data document.
    /// <p/>
    /// All of the variables contained by a ServerDDS <em>must</em> implement the
    /// Projection interface.
    /// 
    /// </summary>
    /// <author>  jhrg
    /// </author>
    /// <version>  $Revision: 15901 $
    /// </version>
    /// <seealso cref="DDS">
    /// </seealso>
    /// <seealso cref="CEEvaluator">
    /// </seealso>
    [Serializable]
    public class ServerDDS : DDS, ICloneable
    {
        //UPGRADE_NOTE: Respective javadoc comments were merged.  It should be changed in order to comply with .NET documentation conventions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1199'"
        /// <summary> Get the dataset filename.
        /// 
        /// </summary>
        /// <returns> The filename of the dataset.
        /// </returns>
        /// <summary> Set the filename of the dataset. This must be passed to the
        /// <code>Read()</code> method of the FileIO interface. The filename of
        /// the dataset may be a real filename or may be any other string that
        /// can be used to identify for the <code>Read</code> method how to
        /// access the data-store of which a particular variable is a member.
        /// 
        /// </summary>
        /// <seealso cref="IServerMethods.Read">
        /// </seealso>
        public virtual String DatasetFilename {
            get {
                String s = Name;
                Console.Out.WriteLine(s);
                return (s);
            }

            set { Name = value; }
        }

        protected internal ServerDDS() {}

        /// <summary> Creates an empty <code>Server DDS</code> with the given dataset name.
        /// 
        /// </summary>
        /// <param name="n">the dataset name
        /// </param>
        protected internal ServerDDS(String n) : base(n) {}

        /// <summary> Creates an empty <code>ServerDDS</code> with the given
        /// <code>BaseTypeFactory</code>. This will be used for OPeNDAP servers
        /// which need to construct subclasses of the various
        /// <code>BaseType</code> objects to hold additional server-side
        /// information.
        /// 
        /// </summary>
        /// <param name="factory">the server <code>BaseTypeFactory</code> object.
        /// </param>
        public ServerDDS(IBaseTypeFactory factory) : base(factory) {}

        /// <summary> Creates an empty <code>ServerDDS</code> with the given dataset name
        /// and <code>BaseTypeFactory</code>. This will be used for OPeNDAP servers
        /// which need to construct subclasses of the various
        /// <code>BaseType</code> objects to hold additional server-side
        /// information.
        /// 
        /// </summary>
        /// <param name="n">      the dataset name
        /// </param>
        /// <param name="factory">the server <code>BaseTypeFactory</code> object.
        /// </param>
        public ServerDDS(String n, IBaseTypeFactory factory) : base(n, factory) {}

        /// <summary> Creates an empty <code>DDS</code> with the given dataset name and
        /// <code>BaseTypeFactory</code>.  This will be used for OPeNDAP servers which
        /// need to construct subclasses of the various <code>BaseType</code> objects
        /// to hold additional server-side information.
        /// 
        /// </summary>
        /// <param name="n">      the dataset name
        /// </param>
        /// <param name="factory">the server <code>BaseTypeFactory</code> object.
        /// </param>
        /// <param name="schema"> the URL where the parser can find an instance of the
        /// OPeNDAP namespace schema.
        /// </param>
        public ServerDDS(String n, IBaseTypeFactory factory, String schema) : base(n, factory, schema) {}


        /// <summary> Return a clone of the <code>ServerDDS</code>. A deep copy is
        /// performed on this object and those it contains.
        /// 
        /// </summary>
        /// <returns> a ServerDDS object.
        /// </returns>
        public override Object Clone() {
            ServerDDS d = (ServerDDS) base.Clone();
            return (d);
        }

        /// <summary> Print the constrained <code>DDS</code> on the given
        /// <code>StreamWriter</code>.
        /// 
        /// </summary>
        /// <param name="os">the <code>StreamWriter</code> to use for output.
        /// </param>
        public virtual void printConstrained(StreamWriter os) {
            //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
            os.WriteLine("Dataset {");
            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            for (IEnumerator e = Variables; e.MoveNext();) {
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                BaseType bt = (BaseType) e.Current;
                if (((IServerMethods) bt).isProject())
                    bt.PrintDeclaration(os, "    ", true, true);
            }
            os.Write("} ");
            if (Name != null)
                os.Write(Name);
            //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
            os.WriteLine(";");
        }

        /// <summary> Print the constrained <code>DDS</code> on the given
        /// <code>OutputStream</code>.
        /// 
        /// </summary>
        /// <param name="os">the <code>OutputStream</code> to use for output.
        /// </param>
        /// <seealso cref="DDS.Print(StreamWriter)">
        /// </seealso>
        public void printConstrained(Stream os) {
            //UPGRADE_WARNING: At least one expression was used more than once in the target code. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1181'"
            StreamWriter pw =
                new StreamWriter(
                    new StreamWriter(new StreamWriter(os, Encoding.Default).BaseStream,
                                     new StreamWriter(os, Encoding.Default).Encoding).BaseStream,
                    new StreamWriter(new StreamWriter(os, Encoding.Default).BaseStream,
                                     new StreamWriter(os, Encoding.Default).Encoding).Encoding);
            printConstrained(pw);
            pw.Flush();
        }


        /// <summary> Print the constrained <code>DDS</code> on the given
        /// <code>OutputStream</code>.
        /// 
        /// </summary>
        /// <param name="os">the <code>OutputStream</code> to use for output.
        /// </param>
        /// <seealso cref="DDS.Print(StreamWriter)">
        /// </seealso>
        /// <opendap.ddx.experimental>  </opendap.ddx.experimental>
        public void printConstrainedXML(Stream os) {
            //UPGRADE_WARNING: At least one expression was used more than once in the target code. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1181'"
            StreamWriter pw =
                new StreamWriter(
                    new StreamWriter(new StreamWriter(os, Encoding.Default).BaseStream,
                                     new StreamWriter(os, Encoding.Default).Encoding).BaseStream,
                    new StreamWriter(new StreamWriter(os, Encoding.Default).BaseStream,
                                     new StreamWriter(os, Encoding.Default).Encoding).Encoding);
            printConstrained(pw);
            pw.Flush();
        }

        /// <summary> Print the constrained <code>DDS</code> on the given
        /// <code>StreamWriter</code>.
        /// 
        /// </summary>
        /// <param name="pw">the <code>StreamWriter</code> to use for output.
        /// </param>
        /// <opendap.ddx.experimental>  </opendap.ddx.experimental>
        public virtual void printConstrainedXML(StreamWriter pw) {
            PrintXML(pw, "", true);
        }
    }
}